提問:呼叫 API 的時候需要帶 token 給後端驗證該怎麼辦?
我們可以使用 HttpInterceptor 進行統一處理!
HttpInterceptor 是用來攔截和處理 HTTP 請求與回應的機制,屬於 Angular HTTPClient module 的一部分。
通常會使用到的情況如下:
- 錯誤處理:
當發生HTTP錯誤時,可以使用HttpInterceptor來統一處理錯誤響應,例如顯示錯誤消息、重新導頁到登錄頁面等等。
Request和Response的修改:
可以在HttpInterceptor中對Request和Response進行修改,例如轉換Body格式、添加Request Header。- 記錄和監控:
在測試或監控的情境中,可以使用HttpInterceptor來記錄所有請求和響應,方便追蹤問題或進行性能分析。
HttpInterceptor的優點是,它可以幫我們集中處理HTTP Request和Response的共用邏輯,減少重複程式碼,增加維護性。不過缺點是它會讓Request和Response的流程變得複雜,尤其是在使用多個HttpInterceptor的情況下。
官方提供了兩種 HttpInterceptor 的實作方式:functional 和 DI-based。
首先我們講講 functional 的方式,這非常簡單,我們只需要 export 一個 function,傳入的參數是 req 和 next,回傳型別則是 Observable<HttpEvent<unknown>>。
接著,在裡面加入我們需要修改的邏輯。以範例來說,我們要在 header 中加入 token。
req:原始的HTTP請求對象,類型為HttpRequest。你可以從這個對象中獲取請求的 URL、標頭、主體等信息。
next:一個HttpHandler,它是請求處理鏈的一部分。你需要通過next.handle(req)將請求傳遞到下一個攔截器或最終的HTTP請求處理。
export function tokenInterceptor(req: HttpRequest<unknown>, next: HttpHandlerFn): Observable<HttpEvent<unknown>> {
   const modifiedReq = req.clone({
      headers: req.headers.set('Authorization', 'Bearer your-token')
   });
   return next.handle(modifiedReq);
}
接著,只需要在 app.config.ts 的 providers 中使用 withInterceptors 這個 method,就大功告成了!
export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(
      withInterceptors([tokenInterceptor]),
    )
  ],
};
DI-based 的實作方式稍微比 functional 的複雜一些,但基本概念是一樣的。我們創建一個可以被注入的 class 並且實作 HttpInterceptor 介面。HttpInterceptor 介面中定義了 intercept 的 method。
@Injectable()
export class TokenInterceptor implements HttpInterceptor {
  intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
    const modifiedReq = req.clone({
      headers: req.headers.set('Authorization', 'Bearer your-token')
    });
    return next.handle(modifiedReq);
  }
}
接著在 app.config.ts 的 providers 中使用 withInterceptorsFromDi 這個 method,並在下方用 HTTP_INTERCEPTORS Token 來註冊我們創建的 Interceptor。
export const appConfig: ApplicationConfig = {
  providers: [
    provideHttpClient(
      // DI-based
      withInterceptorsFromDi(),
    ),
    { provide: HTTP_INTERCEPTORS, useClass: TokenInterceptor, multi: true },
  ],
};
token 用來告訴 Angular 這個 provider 是用來進行 HTTP 攔截的,useClass 則是告訴 Angular 要實作的 class 是哪一個,multi 則是代表可以有多個 HttpInterceptor。
到這邊,我們的 HttpInterceptor 實作就告一段落了!下一篇文章我們會分享商城購物車的實作!